#ifndef __LIST_H
#define __LIST_H

#include <stddef.h>

struct list_head {
    struct list_head *prev, *next;
};


//--------------------------------------------------------------------------
//  init list
//--------------------------------------------------------------------------
#define LIST_HEAD_INIT(head) { &(name), &(name) }
#define LIST_HEAD(head) struct list_head head = LIST_HEAD_INIT(head)

#define LIST_INIT(head) do {                            \
        (head)->prev = (head); (head)->next = (head);   \
    } while (0)

#define LIST_ENTRY(ptr, type, member)  (                            \
        (type*)((char*)((type*)(ptr)) - offsetof(type, member)))


//--------------------------------------------------------------------------
//  list operator
//--------------------------------------------------------------------------
#define __list_add(node, prev, next) do {       \
        (node)->prev = (prev);                  \
        (node)->next = (next);                  \
        (next)->prev = (node);                  \
        (prev)->next = (node);                  \
    } while (0)

#define __list_del(entry) do {                  \
        (entry)->prev->next = (entry)->next;    \
        (entry)->next->prev = (entry)->prev;    \
    } while (0)

#define __list_del_entry(entry) do {            \
        __list_del(entry);                      \
        (entry)->prev = 0, (entry)->next = 0;   \
    } while (0)

#define __list_splice(list, head) do {                                  \
        struct list_head *first = (list)->next, *last = (list)->prev;   \
        struct list_head *at = (head)->next;                            \
        first->prev = (head), (head)->next = first;                     \
        last->next = at, at->prev = last;                               \
    } while (0)

#define LIST_IS_EMPTY(entry) ((entry) == (entry)->next)

#define LIST_FOREACH(iterator, head, type, member)                      \
    for ((iteartor) = LIST_ENTRY((head)->next, type, member);           \
         &((iterator)->member) != (head);                               \
         (iterator) = LIST_ENTRY((iterator)->member.next, type, member))

#define list_init(entry)          LIST_INIT(entry)
#define list_entry(entry)         LIST_ENTRY(entry)
#define list_is_empty(entry)      LIST_IS_EMPTY(entry)
#define list_foreach(iterator, head, type, member)  \
    LIST_FOREACH(iterator, head, type, member)

#define list_add(node, head)      __list_add(node, head, head->next)
#define list_add_tail(node, head) __list_add(node, head->prev, head)
#define list_del(entry)           __list_del_entry(entry)

#define list_del_init(entry) do {                       \
        __list_del(entry); list_init(entry); } while(0)

#define list_splice(list, head) __list_splice(list, head)

#define list_splice_init(list, head) do {                           \
        __list_splice(list, head); list_init(entry); } while (0)


#endif
